This documentation is for developers that want to integrate ForgeFed into an
existing forge.

If you're interested in the development of the specification itself, see the
[other documentation](contributors.md).

# Overview

The purpose of this server is to make it as simple as possible for forge
developers to integrate ForgeFed into their existing codebase. However, it
should not be considered ready for production websites, since it's still in
very early development.

ForgeFed, as this server, follows the [ActivityPub](https://www.w3.org/TR/activitypub/)
specification but you are not expected to understand ActivityPub in order to
use this server. Reading the specs however could be useful for understanding
what's going on and also also for debugging your code. The
[Activity Vocabulary](https://www.w3.org/TR/activitystreams-vocabulary/) is
expected to be extended with new "Activity Types" and "Actor Types" in order to
meet the requirements of code collaboration.

Your job should be only to notify this server when something happens, for example
when a new issue has been created. The job of this server in turn is to
broadcast the changes to every federation actor that is following your
repository (for example, a remote user). In the same way, this server will notify
you when a remote repository has changed such that you can act accordingly,
for example showing a new message in users' feeds.

# Installing MCFI ForgeFed server

MCFI supports multiple forges, so you can skip this section if you want to use
an instance that is already online.

Download the source code

    git clone https://notabug.org/zplus/mcfi.git

Start by changing the server settings in `settings.py`. Add a new entry to
`forge` in `settings.py`. This is used to authenticate multiple forges.

Create Python virtual environment

    python3 -m venv venv (if this doesn't work, try `virtualenv -p python3 venv`)
    source venv/bin/activate
    pip3 install -r requirements.txt

Start up the server

    gunicorn3 --config gunicorn.py mcfi:application

This server will listen at URLs like `/<actor>` where `<actor>` can be anything
of your choice, for example `/alice` or `/alice/lab2-homework`.

# Using MCFI

MCFI provides federation "endpoints". If you've registered a forge called
"my-forge", MCFI will expose an endpoint at `https://mcfi-domain/my-forge/<actor>`.
You use these endpoints to exchange messages with remote users. `<actor>`
can be anything of your choice, the most common seems to be `/<username>/<repository>`.

**Sending messages**: when a repository on your server has been modified, for
example there is a new commit, you will have to send a HTTP POST request to
`https://mcfi-domain/my-forge/<username>/<repository>` with the changes, so that
remote users following your repository will be notified. The content of the
messages is discussed below.

Example: notify the fediverse about a new commit

    POST https://mcfi-domain/my-forge/alice/lab3-homework
    {
        "@context": "https://www.w3.org/ns/activitystreams",
        "type": "Create",
        "id": "",
        "to": "https://example.org/bob",
        "actor": "https://mcfi-domain/my-forge/alice/lab3-homework",
        "object": {
            "type": "Note",
            "id": "",
            "attributedTo": "https://social.example/alyssa/",
            "to": [ "https://example.org/bob" ],
            "content": "Fix assignment n.2"
        }
    }

**Receiving messages**: when a new message is received, for example when a remote
repository has been modified, MCFI will notify you with a HTTP POST request to your
website at the `callback` URL defined in `settings.py`. For instance, if
`callback="https://yourwebsite.org/forgefed/"`, you will receive POST requests at
`https://yourwebsite.org/forgefed/<actor>`.

Example: add a simple controller to handle federation notifications

    @post('/<username>')
    def notify_user(username):
        # Read JSON data that was sent with the request
        # Show a message to your user about this notification

    @post('/<username>/<repository>')
    def notify_repository(username, repository):
        # Read JSON data that was sent with the request
        # Do something with this notification, for example if it's a comment you will
        # show it in a ticket thread

If no `callback` is defined, you will receive no new notifications. This also
means that you won't need to implement any controller. But, if you want to get
the notifications you will have to poll MCFI by sending GET requests to the
endpoints.

# Messages

Messages are well defined JSON objects that are exchanged between MCFI and your
registered forge. By following the specification you can notify, and be notified of,
changes on remote instances.
[They are described here](messages.md). **Please note that these messages are
still experimental and not standardized yet**.






